#include <common.h>

unsigned int printposition = 0;
unsigned char *videoram = (unsigned char *)0xB8000;

char * itoa( int value, int base )
{
    char * rc;
    char * ptr;
    char * low;
	char * str = "";
    // Check for supported base.
    if ( base < 2 || base > 36 )
    {
        *str = '\0';
        return str;
    }
    rc = ptr = str;
    // Set '-' for negative decimals.
    if ( value < 0 && base == 10 )
    {
        *ptr++ = '-';
    }
    // Remember where the numbers start.
    low = ptr;
    // The actual conversion.
    do
    {
        // Modulo is negative for negative value. This trick makes abs() unnecessary.
        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + value % base];
        value /= base;
    } while ( value );
    // Terminating the string.
    *ptr-- = '\0';
    // Invert the numbers.
    while ( low < ptr )
    {
        char tmp = *low;
        *low++ = *ptr;
        *ptr-- = tmp;
    }
    return rc;
}

void scroll_screen()
{
	int i;
	for (i = 160; i < 4000; i += 2)
	{
		videoram[i-160] = videoram[i];
		videoram[i] = 0;
	}
	printposition = 3840;
}

char is_newline()
{
	if (printposition % 160 == 0)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

void newline()
{
	if (printposition >= 3840) {
		scroll_screen();
	}
	else
	{
		printposition = ((printposition / 160) * 160) + 160;
	}
}

void
print_char_col(unsigned char c, unsigned char col)
{
		if (c != 0) {
		if (printposition >= 3999)
		{
			scroll_screen();
		}
		
		if (c == '\n') newline();
		else if (c == '\b')
		{
			if (!(printposition < 2))
			{
				videoram[printposition-1] = 0x0F;
				videoram[printposition-2] = 0;
				printposition -= 2;
			}
		}
		else
		{
			videoram[printposition] = c;
			videoram[printposition+1] = col;
			printposition += 2;
		}
	}
}

void
print_col(char *c, unsigned char col)
{
	int i = 0;
	while (c[i])
	{
		print_char_col(c[i++], col);
	}
}

void
print_char(unsigned char c)
{
	if (c != 0) {
		if (printposition >= 3999)
		{
			scroll_screen();
		}
		
		if (c == '\n') newline();
		else if (c == '\b')
		{
			if (!(printposition < 2))
			{
				videoram[printposition-1] = 0x0F;
				videoram[printposition-2] = 0;
				printposition -= 2;
			}
		}
		else
		{
			videoram[printposition] = c;
			videoram[printposition+1] = 0x0F;
			printposition += 2;
		}
	}
}

void
print(char *c)
{
	int i = 0;
	while (c[i])
	{
		print_char(c[i++]);
	}
}

void
clear_screen()
{
	int i;
	for (i = 0; i < 4000; i++)
	{
		videoram[i] = 0;
	}
	printposition = 0;
}

void print_OK()
{
	print_col("[", 0x09);
	print_col("OK", 0x0A);
	print_col("]", 0x09);
}

void print_ERR()
{
	print_col("[", 0x09);
	print_col("!!", 0x0C);
	print_col("]", 0x09);
}